package com.yzc.android.ui.base.fragment;

import android.content.Context;
import android.os.Bundle;
import android.os.Process;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import android.widget.Toast;

import butterknife.ButterKnife;
import com.yzc.android.KDApp;
import com.yzc.android.R;
import com.yzc.android.ui.base.ActivityCollector;
import com.yzc.android.ui.base.IKDActivity;
import com.yzc.android.ui.base.lifecycle.IComponentContainer;
import com.yzc.android.ui.base.lifecycle.ILifeCycleComponent;
import com.yzc.android.ui.base.lifecycle.LifeCycleComponentManager;
import com.yzc.android.utils.CLog;
import com.yzc.android.utils.DebugConst;
import com.yzc.android.widget.RentalsSunHeaderView;
import in.srain.cube.views.ptr.PtrClassicDefaultHeader;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.header.MaterialHeader;
import in.srain.cube.views.ptr.header.StoreHouseHeader;

/**
 * Created by yzc on 16/4/7.
 *
 * 3.0之前如果要在activity中嵌入fragment, 业务activity要从此类继承
 *
 */
public abstract class KDBaseFragmentActivity extends FragmentActivity implements IComponentContainer, IKDActivity {

    protected boolean mIsForeground = false;

    private LifeCycleComponentManager mComponentContainer = new LifeCycleComponentManager();

    private final static String LOG_TAG = "cube-fragment";

    private static final boolean DEBUG = DebugConst.DEBUG_LIFE_CYCLE;

    protected KDFragment mCurrentFragment;
    private boolean mCloseWarned;

    protected PtrFrameLayout mPtrFrameLayout;
    protected FrameLayout mContainerLayout;
    protected PtrUIHandler mDefaultHeader;

    /**
     * return the string id of close warning
     * <p/>
     * return value which lower than 1 will exit instantly when press back key
     *
     * @return
     */
    protected String getCloseWarning()
    {
        return "Tap back once more to exit.";
    }

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.layout_activity_base_no_navbar);
        mContainerLayout = (FrameLayout) findViewById(R.id.main_view_container);
        mPtrFrameLayout = (PtrFrameLayout) findViewById(R.id.main_view_ptr_frame_layout);
        ButterKnife.bind(this);

        KDApp.getInstance().init();

        if (enablePullRefresh()) {
            // 下拉刷新
            loadDefaultRefreshHeader();
            //loadStoreHouseRefreshHeader();
            //loadMaterialRefreshHeader();
            //loadRentalRefreshHeader();
        }

        //EventBusManager.bindContainerAndHandler(this, new EventLifeCycleHandler()
        //{
        //    public void onEvent(NetworkStateEvent event) {
        //        LogUtils.d(NetworkStatusManager.getInstance().getNetworkTypeName());
        //    }
        //}).tryToRegisterIfNot();
    }

    private void loadDefaultRefreshHeader()
    {
        PtrClassicDefaultHeader defaultHeader = new PtrClassicDefaultHeader(this);
        mPtrFrameLayout.removePtrUIHandler(mDefaultHeader);
        mPtrFrameLayout.setHeaderView(defaultHeader);
        mPtrFrameLayout.addPtrUIHandler(defaultHeader);
        mPtrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(final PtrFrameLayout frame, final View content, final View header) {
                boolean canDoPullDown = PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
                return canDoPullDown && enablePullRefresh();
            }

            @Override
            public void onRefreshBegin(final PtrFrameLayout frame) {
                frame.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mPtrFrameLayout.refreshComplete();
                        pullToRefreshHandler();
                    }
                }, 1800);
            }
        });
        mDefaultHeader = defaultHeader;
    }

    private void loadStoreHouseRefreshHeader()
    {
        StoreHouseHeader houseHeader = new StoreHouseHeader(this);

        //houseHeader.initWithString("XCode Big Air");
        houseHeader.initWithStringArray(R.array.akta);
        mPtrFrameLayout.removePtrUIHandler(mDefaultHeader);
        mPtrFrameLayout.setHeaderView(houseHeader);
        mPtrFrameLayout.addPtrUIHandler(houseHeader);
        mPtrFrameLayout.autoRefresh(false);
        mPtrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(final PtrFrameLayout frame, final View content, final View header) {
                boolean canDoPullDown = PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
                return canDoPullDown && enablePullRefresh();
            }

            @Override
            public void onRefreshBegin(final PtrFrameLayout frame) {
                frame.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mPtrFrameLayout.refreshComplete();
                        pullToRefreshHandler();
                    }
                }, 1800);
            }
        });
        mDefaultHeader = houseHeader;
    }

    private void loadMaterialRefreshHeader()
    {
        MaterialHeader materialHeader = new MaterialHeader(this);
        int[] colors = getResources().getIntArray(R.array.google_colors);
        materialHeader.setColorSchemeColors(colors);
        materialHeader.setLayoutParams(new PtrFrameLayout.LayoutParams(-1, -2));
        materialHeader.setPadding(0, 15, 0, 10);
        materialHeader.setPtrFrameLayout(mPtrFrameLayout);
        mPtrFrameLayout.removePtrUIHandler(mDefaultHeader);
        mPtrFrameLayout.setHeaderView(materialHeader);
        mPtrFrameLayout.addPtrUIHandler(materialHeader);
        mPtrFrameLayout.autoRefresh(false);
        mPtrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(final PtrFrameLayout frame, final View content, final View header) {
                boolean canDoPullDown = PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
                return canDoPullDown && enablePullRefresh();
            }

            @Override
            public void onRefreshBegin(final PtrFrameLayout frame) {
                frame.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mPtrFrameLayout.refreshComplete();
                        pullToRefreshHandler();
                    }
                }, 1800);
            }
        });
        mDefaultHeader = materialHeader;
    }

    private void loadRentalRefreshHeader() {
        RentalsSunHeaderView rentalsSunHeaderView = new RentalsSunHeaderView(this);
        rentalsSunHeaderView.setUp(mPtrFrameLayout);
        mPtrFrameLayout.removePtrUIHandler(mDefaultHeader);
        mPtrFrameLayout.setHeaderView(rentalsSunHeaderView);
        mPtrFrameLayout.addPtrUIHandler(rentalsSunHeaderView);
        mPtrFrameLayout.autoRefresh(false);
        mPtrFrameLayout.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(final PtrFrameLayout frame, final View content, final View header) {
                boolean canDoPullDown = PtrDefaultHandler.checkContentCanBePulledDown(frame, content, header);
                return canDoPullDown && enablePullRefresh();
            }

            @Override
            public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
                ptrFrameLayout.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mPtrFrameLayout.refreshComplete();
                        pullToRefreshHandler();
                    }
                }, 1800);
            }
        });
        mDefaultHeader = rentalsSunHeaderView;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mIsForeground = true;
        mComponentContainer.onBecomesVisibleFromPartiallyInvisible();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mIsForeground = false;
        mComponentContainer.onBecomesPartiallyInvisible();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        mComponentContainer.onBecomesVisibleFromTotallyInvisible();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mComponentContainer.onBecomesTotallyInvisible();
    }

    @Override
    public void addComponent(ILifeCycleComponent component) {
        mComponentContainer.addComponent(component);
    }


    public void pushFragmentToBackStack(Class<?> cls, Object data) {
        FragmentParam param = new FragmentParam();
        param.cls = cls;
        param.data = data;
        goToThisFragment(param);
    }

    protected String getFragmentTag(FragmentParam param) {
        StringBuilder sb = new StringBuilder(param.cls.toString());
        return sb.toString();
    }

    private void goToThisFragment(FragmentParam param) {
        Class<?> cls = param.cls;
        if (cls == null) {
            return;
        }
        try {
            String fragmentTag = getFragmentTag(param);
            FragmentManager fm = getSupportFragmentManager();
            if (DEBUG) {
                CLog.d(LOG_TAG, "before operate, stack entry count: %s", fm.getBackStackEntryCount());
            }
            KDFragment fragment = (KDFragment) fm.findFragmentByTag(fragmentTag);
            if (fragment == null) {
                fragment = (KDFragment) cls.newInstance();
            }
            if (mCurrentFragment != null && mCurrentFragment != fragment) {
                mCurrentFragment.onLeave();
            }
            fragment.onEnter(param.data);

            FragmentTransaction ft = fm.beginTransaction();
            if (fragment.isAdded()) {
                if (DEBUG) {
                    CLog.d(LOG_TAG, "%s has been added, will be shown again.", fragmentTag);
                }
                ft.show(fragment);
            } else {
                if (DEBUG) {
                    CLog.d(LOG_TAG, "%s is added.", fragmentTag);
                }
                ft.add(R.id.main_view_container, fragment, fragmentTag);
            }
            mCurrentFragment = fragment;

            ft.addToBackStack(fragmentTag);
            ft.commitAllowingStateLoss();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        mCloseWarned = false;
    }

    public void goToFragment(Class<?> cls, Object data) {
        if (cls == null) {
            return;
        }
        KDFragment fragment = (KDFragment) getSupportFragmentManager().findFragmentByTag(cls.toString());
        if (fragment != null) {
            mCurrentFragment = fragment;
            fragment.onBackWithData(data);
        }
        getSupportFragmentManager().popBackStackImmediate(cls.toString(), 0);
    }

    public void popTopFragment(Object data) {
        FragmentManager fm = getSupportFragmentManager();
        fm.popBackStackImmediate();
        if (tryToUpdateCurrentAfterPop() && mCurrentFragment != null) {
            mCurrentFragment.onBackWithData(data);
        }
    }

    public void popToRoot(Object data) {
        FragmentManager fm = getSupportFragmentManager();
        while (fm.getBackStackEntryCount() > 1) {
            fm.popBackStackImmediate();
        }
        popTopFragment(data);
    }

    /**
     * process the return back logic
     * return true if back pressed event has been processed and should stay in current view
     *
     * @return
     */
    protected boolean processBackPressed() {
        return false;
    }

    /**
     * process back pressed
     */
    @Override
    public void onBackPressed() {

        // process back for fragment
        if (processBackPressed()) {
            return;
        }

        // process back for fragment
        boolean enableBackPressed = true;
        if (mCurrentFragment != null) {
            enableBackPressed = !mCurrentFragment.processBackPressed();
        }
        if (enableBackPressed) {
            int cnt = getSupportFragmentManager().getBackStackEntryCount();
            if (cnt <= 1 && isTaskRoot()) {
                String closeWarningHint = getCloseWarning();
                if (!mCloseWarned && !TextUtils.isEmpty(closeWarningHint)) {
                    Toast toast = Toast.makeText(this, closeWarningHint, Toast.LENGTH_SHORT);
                    toast.show();
                    mCloseWarned = true;
                } else {
                    doReturnBack();
                }
            } else {
                mCloseWarned = false;
                doReturnBack();
            }
        }
    }

    @Override
    public boolean enableDefaultBack() {
        return true;
    }

    @Override
    public boolean enablePullRefresh() {
        return false;
    }

    @Override
    public void pullToRefreshHandler() {

    }

    private boolean tryToUpdateCurrentAfterPop() {
        FragmentManager fm = getSupportFragmentManager();
        int cnt = fm.getBackStackEntryCount();
        if (cnt > 0) {
            String name = fm.getBackStackEntryAt(cnt - 1).getName();
            Fragment fragment = fm.findFragmentByTag(name);
            if (fragment != null && fragment instanceof KDFragment) {
                mCurrentFragment = (KDFragment) fragment;
            }
            return true;
        }
        return false;
    }

    protected void doReturnBack() {
        int count = getSupportFragmentManager().getBackStackEntryCount();
        if (count <= 1) {
            finish();
            android.os.Process.killProcess(Process.myPid());
            System.exit(1);
        } else {
            getSupportFragmentManager().popBackStackImmediate();
            if (tryToUpdateCurrentAfterPop() && mCurrentFragment != null) {
                mCurrentFragment.onBack();
            }
        }
    }

    public void hideKeyboardForCurrentFocus() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (getCurrentFocus() != null) {
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    }

    public void showKeyboardAtView(View view) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }

    public void forceShowKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

    }

    protected void exitFullScreen() {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    }
}
